Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V2 update/gas optimization #69

Draft
wants to merge 5 commits into
base: v2
Choose a base branch
from
Draft

Conversation

Kayanski
Copy link
Contributor

@Kayanski Kayanski commented Apr 11, 2024

This PR aims at adding a cache system for yield positions to avoid expensive queries.
We introduce 2 things :

  1. Added mutable reference to positions in trait to be able to save cache when using the object for queries.
  2. Added a stop to avoid storing that extra cache

This allows reducing gas price from 3.1M to 2.1M for an add-to-position operation

@Kayanski Kayanski marked this pull request as draft April 11, 2024 23:52
Copy link
Contributor

@Buckram123 Buckram123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this type of cache gonna be very hard to manage and will spawn accidental bugs. From what I spotted with glance is autocompound doesn't reset position, meaning it won't notice new rewards until deposit/position update called, but I don't think bot should be allowed to call update (no check of sender there, but it looks like it should be admin method)

If I had to propose something:
What do you think about loading it at the start of every method that needs it and re-using for this method?
So for example you will have Strategy::load_osmosis_positions and it will return [(position_id, FullPositionBreakdown)] that you have to pass into all of the methods that can require FullPositionBreakdown. In the worst case you'll have to do some clones, but it should be cheaper than serialize/deserialize/store it completely and easier to manage

Comment on lines +38 to +39
// This is a cache to avoid querying the position information as this query is expensive
pub position_cache: Option<FullPositionBreakdown>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This query is expensive and serializing/deserializing/saving in state this structure is also expensive(it's pretty huge), so if we do cache it between calls I don't think we should be sending all of it on every message, but only information that we absolutely need for this execution.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I'm NEVER saving the structure in state ! This field is just there to store the cache temporarily

Copy link
Contributor

@Buckram123 Buckram123 Apr 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I'm NEVER saving the structure in state ! This field is just there to store the cache temporarily

Ah, I see, thanks for clearing that up. Although I would prefer to keep it separately so it doesn't get stored accidentally and no time or gas wasted for serializing/deserializing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I make the storage structure private, it might solve the issue

Copy link
Contributor

@Buckram123 Buckram123 Apr 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I make the storage structure private, it might solve the issue

You can make wrapper around Strategy that will have this field(or other useful fields for other protocols) like

StrategyFetched{
  strategy: Strategy,
  osmosis_positions: HashSet<position_id, FullPositionBreakDown>,
  // .. other useful info after fetching strategies
}

@Kayanski
Copy link
Contributor Author

I feel like this type of cache gonna be very hard to manage and will spawn accidental bugs. From what I spotted with glance is autocompound doesn't reset position, meaning it won't notice new rewards until deposit/position update called, but I don't think bot should be allowed to call update (no check of sender there, but it looks like it should be admin method)

If I had to propose something: What do you think about loading it at the start of every method that needs it and re-using for this method? So for example you will have Strategy::load_osmosis_positions and it will return [(position_id, FullPositionBreakdown)] that you have to pass into all of the methods that can require FullPositionBreakdown. In the worst case you'll have to do some clones, but it should be cheaper than serialize/deserialize/store it completely and easier to manage

I'm not storing anything here ! It's just stored temporarily in the strategy object. The serialize/deserialize part is not that expensive either.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants